﻿using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using ZoeEngine.Framework;
using ZoeEngine.Components.Physics;
using ZoeEngine.Services.Content;

namespace ZoeEngine.Components.Graphics
{
    [ComponentDependency(typeof(BaseSpatialComponent))]
    public class SpriteRenderComponent : BaseRenderComponent
    {
        private BaseSpatialComponent _spatialComp;

        private string _assetPath;
        private Texture2D _bitmapSheet;
        private Point _frameSize = new Point(32, 32);
        private Point _frameSpace = new Point(1, 1);
        private SpriteEffects _spriteEffects = SpriteEffects.None;
        private float _scale = 1;
        private bool _isLoaded = false;

        private int _currentFrame = 0;
        private Rectangle _currentFrameRect;

        public SpriteRenderComponent(string assetPath)
        {
            this._assetPath = assetPath;
        }
        internal void BuildFrames()
        {
            // Validate the frame space of the sprite sheet.
            if(_isLoaded)
                _frameSpace = new Point(_bitmapSheet.Width / _frameSize.X, _bitmapSheet.Height / _frameSize.Y);

            // Regenerate the current frame rectangle.
            _currentFrameRect = new Rectangle((_currentFrame % _frameSpace.X) * _frameSize.X,
                                              (_currentFrame / _frameSpace.X) * _frameSize.Y,
                                              _frameSize.X, _frameSize.Y);
        }

        public override void Initialize()
        {
            base.Initialize();
            _spatialComp = this.Owner.Find<BaseSpatialComponent>();
        }
        public override void Start()
        {
            base.Start();
        }
        public override void LoadContent()
        {
            if (!_isLoaded)
            {
                // Load the sprite sheet asset specified.
                _bitmapSheet = Zoe.GetService<IContentService>().Load<Texture2D>(_assetPath);
                _isLoaded = true;

                // Build frames from the loaded sprite sheet.
                BuildFrames();
            }
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(_bitmapSheet,
                             _spatialComp.Position,
                             _currentFrameRect,
                             Color.White,
                             _spatialComp.Rotation,
                             new Vector2(_frameSize.X / 2, _frameSize.Y / 2),
                             _scale,
                             _spriteEffects,
                             0);
        }
        public override void UnloadContent()
        {
            base.UnloadContent();
        }

        public int CurrentFrame
        {
            get
            {
                return _currentFrame;
            }
            set
            {
                _currentFrame = value;
                BuildFrames();
            }
        }
        public float Scale
        {
            get
            {
                return _scale;
            }
            set
            {
                _scale = value;
            }
        }
        public Point FrameSize
        {
            get
            {
                return _frameSize;
            }
            set
            {
                _frameSize = value;
                BuildFrames();
            }
        }
        public SpriteEffects SpriteEffects
        {
            get
            {
                return _spriteEffects;
            }
            set
            {
                _spriteEffects = value;
            }
        }
    }
}
